<?php

namespace app\api\controller;

use app\admin\service\admin\FileService;

use app\common\Constants;
use app\common\service\CaptchaService;
use app\common\service\VerificationCodeService;
use OpenApi\Attributes as OA;
use think\App;
use think\exception\ValidateException;
use think\facade\Log;

class Base extends Api
{
    public function __construct(
        App $app,
        protected VerificationCodeService $verificationCodeService,
    )
    {
        parent::__construct($app);
    }

    #[OA\Post(
        path: "/api/base/sendEmailCode",
        description: "发送邮件验证码",
        summary: "发送邮件验证码",
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                properties: [
                    new OA\Property(property: "email", description: "邮件地址", type: "string", example: 'test@163.com'),
                    new OA\Property(property: "username", description: "用户名", type: "string", example: '张三'),
                ],
                type: "object"
            )
        ),
        tags: ["基本接口"],
        responses: [
            new OA\Response(
                response: 200,
                description: "操作成功",
                content: new OA\JsonContent(ref: "#/components/schemas/SuccessResponse")
            ),
        ]
    )]
    public function sendEmailCode(): \think\response\Json
    {
        $email = $this->request->post('email');
        $username = $this->request->post('username', '用户');

        if (empty($email)) {
            throw new ValidateException(Constants::E_COMMON_DATA_VALIDATION_FAILED);
        }

        $code = $this->verificationCodeService->generateCode();
        $key = Constants::CACHE_VERIFICATION_CODE_KEY . $email;
        $this->verificationCodeService->cacheCode($key, $code);

        if (app()->isDebug()) {
            $data = ['mail' => $email, 'code' => $code];
            Log::write($data, 'debug');
            return $this->success(['data' => $data]);
        } else {
            $result = $this->verificationCodeService->send('email', $email, $code, ['username' => $username]);
            if ($result) {
                return $this->success();
            } else {
                return $this->error();
            }
        }
    }

    #[OA\Post(
        path: "/api/base/sendSmsCode",
        description: "发送短信验证码",
        summary: "发送短信验证码",
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                properties: [
                    new OA\Property(property: "mobile", description: "手机号码", type: "string", example: '13988889999'),
                ],
                type: "object"
            )
        ),
        tags: ["基本接口"],
        responses: [
            new OA\Response(
                response: 200,
                description: "操作成功",
                content: new OA\JsonContent(ref: "#/components/schemas/SuccessResponse")
            ),
        ]
    )]
    public function sendSmsCode(): \think\response\Json
    {
        $mobile = $this->request->post('mobile');

        if (empty($mobile)) {
            throw new ValidateException(Constants::E_COMMON_DATA_VALIDATION_FAILED);
        }

        $code = $this->verificationCodeService->generateCode();
        $key = Constants::CACHE_VERIFICATION_CODE_KEY . $mobile;
        $this->verificationCodeService->cacheCode($key, $code);

        if (app()->isDebug()) {
            $data = ['mobile' => $mobile, 'code' => $code];
            Log::write($data, 'debug');
            return $this->success(['data' => $data]);
        } else {
            $this->verificationCodeService->send('sms', $mobile, $code);
            return $this->success();
        }
        // $this->verificationCodeService->send('sms', $mobile, $code);
        // return $this->success();
    }
    #[OA\Post(
        path: "/api/base/captcha",
        description: "匿名获得验证码",
        summary: "生成验证码",
        tags: ["基本接口"],
        responses: [
            new OA\Response(
                response: 200,
                description: "操作成功",
                content: new OA\JsonContent(ref: "#/components/schemas/SuccessResponse")
            ),
        ]
    )]
    public function captcha(): \think\response\Json
    {
        $captcha = CaptchaService::getCaptcha();
        return $this->success(["data" => $captcha]);
    }

    #[OA\Post(
        path: "/api/base/upload",
        description: "文件上传接口",
        summary: "文件上传接口，支持图片、文档等多种文件类型，并可区分编辑器上传还是普通上传",
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                properties: [
                    new OA\Property(property: "file", description: "上传的文件", type: "string", format: "binary"),
                    new OA\Property(property: "edit", description: "是否为编辑器上传 (可选)", type: "string", nullable: true)
                ]
            )
        ),
        tags: ["基本接口"],
        responses: [
            new OA\Response(
                response: 200,
                description: "操作成功",
                content: new OA\JsonContent(
                    ref: "#/components/schemas/SuccessResponse",
                    properties: [
                        new OA\Property(
                            property: "data",
                            description: "上传文件返回的详细信息",
                            properties: [
                                new OA\Property(property: "url", description: "文件访问URL", type: "string", example: "/uploads/admin/202510/68f6ceb99f62c.jpeg"),
                                new OA\Property(property: "hash", description: "文件内容的MD5哈希值", type: "string", example: "ba567da61bd08c931703606f4337986d"),
                                new OA\Property(property: "extension", description: "文件扩展名", type: "string", example: "jpeg"),
                                new OA\Property(property: "name", description: "文件原始名称", type: "string", example: "湖.jpeg"),
                                new OA\Property(property: "mime", description: "文件MIME类型", type: "string", example: "image/jpeg"),
                                new OA\Property(property: "size", description: "文件大小（字节）", type: "integer", example: 426591),
                                new OA\Property(property: "edit", description: "文件编辑信息", type: "string", example: null, nullable: true),
                                new OA\Property(property: "create_id", description: "创建用户ID", type: "integer", example: 8934534),
                                new OA\Property(property: "create_dept", description: "创建部门ID", type: "integer", example: 0),
                                new OA\Property(property: "status", description: "文件状态 (1: 正常)", type: "integer", example: 1),
                                new OA\Property(property: "create_time", description: "创建时间", type: "string", format: "date-time", example: "2025-10-21 08:07:21"),
                                new OA\Property(property: "update_time", description: "更新时间", type: "string", format: "date-time", example: "2025-10-21 08:07:21"),
                                new OA\Property(property: "id", description: "文件记录ID", type: "integer", example: 5)
                            ],
                            type: "object"
                        )
                    ]
                )
            ),
        ]
    )]
    public function upload(): \think\response\Json
    {
        $file = $this->request->file('file');
        $edit = $this->request->post('edit');
        // 检查上传的文件是否符合要求
        FileService::validateFileType($file);
        // 查询是否已经存在相同的文件，如果有就不再上传了
        $fileInfo = FileService::getSameFileUrl($file);
        // 如果返回了相同的文件地址，则直接返回，否则执行查询
        if ($fileInfo) {
            return $this->success(['data' => $fileInfo]);
        } else {
            return $this->success(['data' => FileService::doUpload($file, $edit)]);
        }
    }
}